package com.qiyu.tech.web.starter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qiyu.common.annotations.RequireLogin;
import com.qiyu.mall.user.interfaces.dto.LoginDTO;
import com.qiyu.mall.user.interfaces.dto.WorkerDTO;
import com.qiyu.mall.user.interfaces.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

import static com.qiyu.common.constants.MiniProgramConstants.CONTENT_TYPE_JSON;


/**
 * @author linhao
 * @date 2019/7/29
 * @Version V1.0
 */
@Component(value = "accessControlInterceptorImpl")
@Slf4j
public class AccessControlInterceptor implements HandlerInterceptor {

    @Resource
    private ObjectMapper objectMapper;

    @Reference
    private AuthService authService;


    public static List<String> whiteList = Arrays.asList("/common/mini-blind-date/error");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String uri = request.getRequestURI();
        log.info("request URI={}", uri);
        //白名单url地址
        if (uri.indexOf("swagger") > 0 || uri.indexOf("error") > 0) {
            return true;
        }
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        RequireLogin requireLogin = method.getAnnotation(RequireLogin.class);
        if (requireLogin != null && !requireLogin.value()) {
            return true;
        }
        String token = request.getHeader("App-Token");
        if (!StringUtils.isEmpty(token)) {
            LoginDTO loginDTO = authService.checkToken(token);
            if (loginDTO == null) {
                log.warn("[AccessControlInterceptor]--token非法");
                printUnauthorizedResponse(response);
                return false;
            } else {
                SecurityContextHolder.setCurrentUser(loginDTO.getAccountId());
                SecurityContextHolder.setTokenHolder(token);
                return true;
            }
        }
        String webSysToken = request.getHeader("mini_web_token");
        if (webSysToken != null) {
            WorkerDTO workerDTO = authService.getWorker(webSysToken);
            if (workerDTO == null) {
                log.warn("[AccessControlInterceptor]--worker--token非法");
                printUnauthorizedResponse(response);
                return false;
            } else {
                SecurityContextHolder.setCurrentWorker(workerDTO);
                return true;
            }
        }
        printUnauthorizedResponse(response);
        return false;
    }


    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        SecurityContextHolder.clearContext();
    }


    /**
     * 无权限访问页面
     *
     * @param response
     * @throws IOException
     */
    private void printUnauthorizedResponse(HttpServletResponse response) throws IOException {
        response.setContentType(CONTENT_TYPE_JSON);
        response.setCharacterEncoding("UTF-8");
        objectMapper.writer().writeValue(response.getWriter(), com.qiyu.common.utils.ResponseUtil.Unauthorized());
    }
}
